/**
 * 
 */
package com.nwpusp.controller;

import java.util.ArrayList;

import android.util.Log;

import com.nwpusp.controller.actions.*;
import com.nwpusp.model.GameModel;

/**
 * @author JustinCao
 *
 */
public class ActionDispatcher {
	private class ActionDispatchThread extends Thread {
		ActionDispatcher dispatcher = null;
		private boolean endTag = false;
		public ActionDispatchThread(ActionDispatcher dispatcher) {
			this.dispatcher = dispatcher;
			endTag = false;
		}
		public void setEnd() {
			endTag = true;
		}
		public void run() {
			while(!endTag && dispatcher != null) {
					ArrayList<DispathInfo> ds = dispatcher.fetchDispatchInfos();
					for(DispathInfo di : ds) {
						ArrayList<Action> al = di.al;
						ArrayList<GameActionListener> gals = di.gals;
						if(!al.isEmpty() && !gals.isEmpty()) {
							for(GameActionListener gal : gals) {
								try {
									gal.OnAction(al);
								}
								catch (Exception e) {
									e.printStackTrace();
								}
							}
						}
					}
				}
			}
		}
	
	private class DispathInfo {
		
		public DispathInfo(ArrayList<Action> al, ArrayList<GameActionListener> gals) {
			this.al = al;
			this.gals = gals;
		}
		public ArrayList<Action> al = null;
		public ArrayList<GameActionListener> gals = null;
	}
	
	ActionDispatchThread adt = null;
	private GameModel m = null;
	ArrayList<DispathInfo> dispInfos = new ArrayList<DispathInfo>();
	
	synchronized public void dispatchAction(ArrayList<GameActionListener> ngals, ArrayList<Action> na) {
		Log.d("JustinLog", "dispatchAction invoked");
		
		if(!ngals.isEmpty() && !na.isEmpty()) {
			dispInfos.add(new DispathInfo(na, ngals));
			notifyAll();
		}
	}
	synchronized public ArrayList<DispathInfo> fetchDispatchInfos() {
		ArrayList<DispathInfo> ds = new ArrayList<DispathInfo>();
		if(this.dispInfos.isEmpty()) {
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		ds.addAll(this.dispInfos);
		Clear();
		return ds;
	}
	
	//synchronized public ArrayList<Action> getActionList() {
	//	ArrayList<Action> nal = new ArrayList<Action>(al);
	//	return nal;
	//}
	//synchronized public ArrayList<GameActionListener> getListenerList() {
	//	ArrayList<GameActionListener> ngals =  new ArrayList<GameActionListener>(gals);
	//	return ngals;
	//}
	
	public ActionDispatcher(GameModel m) {
		this.m = m;
		Clear();
		adt = new ActionDispatchThread(this);
		adt.start();
	}
	
	public void Clear() {
		this.dispInfos.clear();
	}
	
	public GameModel getModel() {
		return m;
	}
	@Override
	protected void finalize() throws Throwable {
		if(adt != null) {
			adt.setEnd();
			adt.notify();
		}
		super.finalize();
	}
}
